package cn.org.atool.generator.javafile.template;

import cn.org.atool.generator.database.model.TableSetter;
import com.squareup.javapoet.*;

import javax.lang.model.element.Modifier;

import static cn.org.atool.generator.util.ClassNames.*;
import static com.squareup.javapoet.ClassName.get;

/**
 * <p>
 * TODO
 * </p>
 *
 * @author by lishupeng
 * @date 2022/3/31 22:15
 */
public class ServiceImplementFile extends AbstractTemplateFile {
    public ServiceImplementFile(TableSetter table) {
        super(table);
        this.packageName = getPackage(table);
        this.klassName = getClass(table);
    }

    public static String getPackage(TableSetter table) {
        return table.gc().getBasePackage() + ".impl";
    }

    public static String getClass(TableSetter table) {
        return table.getEntityPrefix() + "ServiceImpl";
    }

    /**
     * 文件构造
     *
     * @param spec
     */
    @Override
    protected void build(TypeSpec.Builder spec) {
        String basePackage = table.gc().getBasePackage();
        String entityPrefix = table.getEntityPrefix();

        //实现接口
        spec.addSuperinterface(ServiceInterfaceFile.getClassName(table));

        //添加注解
        spec.addAnnotation(ClassName.get("org.springframework.stereotype", "Service"));
        spec.addAnnotation(ClassName.get("lombok.extern.slf4j", "Slf4j"));

        //添加父类
        if (table.getSuperServiceImpl() != null) {
            spec.superclass(parameterizedType(
                    ClassName.get(table.getSuperServiceImpl()),
                    EntityFile.entityName(table),
                    DaoInterfaceFile.daoInterfaceName(table),
                    ClassName.get(basePackage + ".wrapper", entityPrefix + "Query"),
                    ClassName.get(basePackage + ".wrapper", entityPrefix + "Update")
            ));
        }

        ClassName ExceptionClz = get("java.lang", "Exception");
        ClassName pageDTOClz = get("com.dminfo.hms.common.domain.dto", "PageDTO");
        ClassName OverrideClz = get("java.lang", "Override");
        ClassName pageVOClz = get("com.dminfo.hms.common.domain.vo", "PageVO");
        ClassName entityClz = get(table.gc().getBasePackage() + ".entity", table.getEntityPrefix() + "Entity");

        AnnotationSpec TransactionalAnnotation = AnnotationSpec.builder(get("org.springframework.transaction.annotation", "Transactional"))
                .addMember("rollbackFor", "$T.class", ExceptionClz)
                .build();

        spec
                .addMethod(MethodSpec.methodBuilder("page")
                        .addAnnotation(OverrideClz)
                        .addJavadoc("分页")
                        .addModifiers(Modifier.PUBLIC)
                        .addParameter(ParameterSpec.builder(pageDTOClz, "dto").build())
                        .returns(ParameterizedTypeName.get(pageVOClz, entityClz))
                        .addStatement("return $T.convert(page(dto, query()))", get("com.dminfo.hms.util","PageUtil"))
                        .build())
                .addMethod(MethodSpec.methodBuilder("list")
                        .addAnnotation(OverrideClz)
                        .addJavadoc("列表")
                        .addModifiers(Modifier.PUBLIC)
                        .addParameter(ParameterSpec.builder(entityClz, "entity").build())
                        .returns(ParameterizedTypeName.get(get("java.util", "List"), entityClz))
                        .addStatement("return listEntity(query())")
                        .build())
                .addMethod(MethodSpec.methodBuilder("getById")
                        .addAnnotation(OverrideClz)
                        .addJavadoc("查询")
                        .addModifiers(Modifier.PUBLIC)
                        .addParameter(ParameterSpec.builder(get("java.lang", "Long"), "id").build())
                        .returns(entityClz)
                        .addStatement("return selectById(id)")
                        .build())
                .addMethod(MethodSpec.methodBuilder("save")
                        .addAnnotation(OverrideClz)
                        .addAnnotation(TransactionalAnnotation)
                        .addJavadoc("保存")
                        .addModifiers(Modifier.PUBLIC)
                        .addParameter(ParameterSpec.builder(entityClz, "entity").build())
                        .addStatement("saveEntity(entity)")
                        .build())
                .addMethod(MethodSpec.methodBuilder("update")
                        .addAnnotation(OverrideClz)
                        .addAnnotation(TransactionalAnnotation)
                        .addJavadoc("更新")
                        .addModifiers(Modifier.PUBLIC)
                        .addParameter(ParameterSpec.builder(entityClz, "entity").build())
                        .addStatement("updateById(entity)")
                        .build())
                .addMethod(MethodSpec.methodBuilder("delete")
                        .addAnnotation(OverrideClz)
                        .addJavadoc("删除")
                        .addAnnotation(TransactionalAnnotation)
                        .addModifiers(Modifier.PUBLIC)
                        .addParameter(ParameterSpec.builder(get("java.lang", "Long"), "id").build())
                        .addStatement("deleteById(id)")
                        .build());
        spec.addJavadoc("$T: 服务类接口实现\n", super.className());
    }

    /**
     * 是否接口类
     *
     * @return ignore
     */
    @Override
    protected boolean isInterface() {
        return false;
    }
}
